<template>
  <div class="imageViewer boxWrapper" ref="svgBox">
    <div v-loading="imageLoading" element-loading-background="rgba(255, 255, 255, 0.7)" element-loading-spinner="el-icon-loading">
      <!-- 提示信息 -->
      <div v-if="selectDrawType == 1 && imageUrl != ''" class="formulaWrapper tips">
        <i class="el-icon-info"></i> 在需要位置点击添加测点配置
      </div>
      <div v-if="selectDrawType == 6 && imageUrl != ''" class="formulaWrapper tips">
        <i class="el-icon-edit"></i> 在需要位置点击添加文字标注
      </div>
      <div v-if="selectDrawType == 2 && !scaleLine && imageUrl != ''" class="formulaWrapper tips">
        <i class="el-icon-rank"></i> 点击设置起点，拖动至终点松开完成绘制
      </div>
      <div v-if="selectDrawType == 2 && scaleLine && imageUrl != ''" class="formulaWrapper tips success">
        <i class="el-icon-success"></i> 比例尺绘制成功！如需修改，请单击画面重新绘制!
      </div>

      <!-- 上传区域 -->
      <div class="uploadFile" v-if="imageUrl == '' && isDigitalization">
        <el-upload class="upload-demo" action="" :http-request="handleUploadBg" :show-file-list="false">
          <div class="upload-content">
            <i class="el-icon-upload"></i>
            <p class="upload-text">暂无底图，点击此处上传</p>
            <p class="upload-subtext">支持JPG、PNG格式，最大5MB</p>
          </div>
        </el-upload>
      </div>

      <div class="uploadFile" v-if="imageUrl == '' && !isDigitalization">
        <div class="upload-content">
          <i class="iconfont">&#xe61c;</i>
          <p class="upload-text">暂无底图，需进行测点关联</p>
        </div>
      </div>

      <!-- SVG画布 -->
      <div id="svgBox" :style="{width:svgW + 'px',height:svgH + 'px'}" v-show="imageUrl !== ''">
          <svg
            :width="`${svgW}px`"
            :height="`${svgH}px`"
            :viewBox="`0 0 ${svgW} ${svgH}`"
            id="svg"
            @mousedown="handleCanvasMousedown"
            @mousemove="handleCanvasMousemove"
            @mouseup="handleCanvasMouseup"
          >
            <!-- 背景图 -->
            <image 
              :href="imageUrl" 
              x="0" 
              y="0" 
              :width="svgW" 
              :height="svgH"
            />

            <!-- 测点 -->
            <g v-if="isDigitalization">
              <g v-for="item in allElementPoint" :key="item.id">
                <circle
                  :cx="item.startX"
                  :cy="item.startY"
                  :r="item.pointSize"
                  :fill="item.color"
                  class="measure-point"
                  @mouseover="handleSvgMouseMove(item, $event)"
                  @mouseleave="handleSvgMouseLeave"
                />
              </g>
            </g>
            <g v-if="!isDigitalization">
            
            <g v-for="(item,index) in allElementPoint" :key="index">
                <!-- 绘制测点 -->
                <circle 
                  :cx="item.startX" 
                  :cy="item.startY" 
                  :r="item.pointSize" 
                  :fill="item.color" 
                  v-if="item.lineType == 1"  
                  @mouseover="handleDigitalizationMouseMove(item, $event)"
                  @mouseleave="handleSvgMouseLeave"/>
                <!-- 绘制线 -->
                <line 
                  :x1="item.startX" 
                  :y1="item.startY" 
                  :x2="item.endX" 
                  :y2="item.endY" 
                  :stroke="item.color" 
                  :stroke-width="item.borderSize || 2" 
                  v-if="item.lineType > 1 && item.lineType < 6" 
                  @mouseover="handleDigitalizationMouseMove(item, $event)"
                  @mouseleave="handleSvgMouseLeave"
                 />
                <!-- 绘制带箭头的线 -->
                <defs>
                <marker id="triangle" markerUnits="strokeWidth" markerWidth="5" markerHeight="4" refX="0" refY="2" orient="auto" >
                    <path d="M 0 0 L 5 2 L 0 4 z" :style="`fill:${item.color}`"/>
                </marker>
                </defs>
                <path :d="`M ${item.startX},${item.startY} L ${item.endX},${item.endY}`" :stroke="item.color" :stroke-width="item.borderSize || 2" fill="none"
                style="marker-end: url(#triangle);" v-if="item.lineType == 6 || item.lineType == 7" 
                @mouseover="handleDigitalizationMouseMove(item, $event)"
                @mouseleave="handleSvgMouseLeave"/>
            </g>
            </g>

            <!-- 文字 -->
            <g v-for="item in allElementText" :key="item.ID">
              <text 
                :x="item.x" 
                :y="item.y" 
                fill="#333" 
              >{{ item.text }}</text>
            </g>

            <!-- 比例尺 -->
            <g>
              <!-- 临时比例尺线（绘制中） -->
              <g v-if="isDrawingScale && scaleStartPoint && tempScalePoint">
                <line
                  v-for="(mark, index) in getTempScaleMarks(scaleStartPoint, tempScalePoint)"
                  :key="'temp-mark-' + index"
                  :x1="mark.x1"
                  :y1="mark.y1"
                  :x2="mark.x2"
                  :y2="mark.y2"
                  stroke="red"
                  :stroke-width="1"
                />
                <line
                  :x1="scaleStartPoint.x"
                  :y1="scaleStartPoint.y"
                  :x2="tempScalePoint.x"
                  :y2="tempScalePoint.y"
                  stroke="red"
                  stroke-width="2"
                />
              </g>

              <!-- 完成的比例尺线 -->
              <g v-if="scaleLine">
                <line
                  v-for="(mark, index) in getScaleMarks(scaleLine)"
                  :key="'final-mark-' + index"
                  :x1="mark.x1"
                  :y1="mark.y1"
                  :x2="mark.x2"
                  :y2="mark.y2"
                  stroke="red"
                  :stroke-width="1.5"
                />
                <line
                  :x1="scaleLine.x1"
                  :y1="scaleLine.y1"
                  :x2="scaleLine.x2"
                  :y2="scaleLine.y2"
                  stroke="red"
                  stroke-width="2.5"
                />
              </g>

              <!-- 比例尺文字 -->
              <text
                v-if="scaleLine"
                :x="(scaleLine.x1 + scaleLine.x2) / 2"
                :y="(scaleLine.y1 + scaleLine.y2) / 2 - 15"
                fill="red"
                font-size="14"
                font-weight="bold"
                text-anchor="middle"
                class="scale-text"
              >
                {{ scaleLength.toFixed(2) }} 像素
              </text>
            </g>
          </svg>
      </div>

      <!-- 测点信息悬浮窗 - 移动到SVG画布外部 -->
      <div
        class="pointTool"
        :style="`left:${positonX}px;top:${positonY}px;`"
        v-show="pointToolShow"
      >
        <div class="point-tool-header">
          <i class="el-icon-location-information"></i>
          <span>测点信息</span>
        </div>
        <div class="point-tool-content">
          <p><span class="label">测点名称：</span>{{ pointPlayer.pointName }}</p>
          <p><span class="label">X坐标：</span>{{ pointPlayer.startX }}</p>
          <p><span class="label">Y坐标：</span>{{ pointPlayer.startY }}</p>
          <p><span class="label">测点颜色：</span>
            <span><span class="color-badge" :style="`background-color: ${pointPlayer.color}`"></span>
            {{ pointPlayer.color }}</span>                
          </p>
          <p><span class="label">测点半径：</span>{{ pointPlayer.pointSize }}像素</p>
        </div>
      </div>

      <!-- 线信息悬浮窗 - 移动到SVG画布外部 -->
      <div
        class="pointTool"
        :style="`left:${positonX}px;top:${positonY}px;`"
        v-show="pointToolShowLine"
      >
        <div class="point-tool-header">
          <i class="el-icon-location-information"></i>
          <span>线信息</span>
        </div>
        <div class="point-tool-content">
          <p><span class="label">名称：</span>{{ lineTips[0] }}</p>
          <p><span class="label">测值：</span>{{ lineTips[1] }}</p>
          <p><span class="label" v-if="lineTips[2]">参照值：</span>{{ lineTips[2]}}</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ImageViewer',
  props: {
    imageUrl: {
      type: String,
      default: ''
    },
    graphTreeID: {
      type: [String, Number],
      default: null
    },
    selectDrawType: {
      type: [String, Number],
      default: ''
    },
    allElementPoint: {
      type: Array,
      default: () => []
    },
    allElementText: {
      type: Array,
      default: () => []
    },
    externalScaleLine: {
        type: Object,
        default: () => ({}),
        required: false
    },
    isDigitalization:{
       type:Boolean,
       default:false
    }
  },
  data() {
    return {
      imageLoading: false,
      svgW: 100,
      svgH: 100,
      imageRef: null,
      pointToolShow: false,
      positonY: '',
      positonX: '',
      pointPlayer: {},
      isDrawingScale: false,
      scaleStartPoint: null,
      tempScalePoint: null,
      scaleLine: null,
      scaleLength: 0,
      pointToolShowLine:false,
      lineTips:[],
      svgBoxOffset: { left: 0, top: 0 } // 存储SVG容器的偏移量
    };
  },
  watch: {
    imageUrl: {
      immediate: true,
      handler(newVal) {
        if (newVal) {
          this.calculationImage(newVal);
        }
      }
    },
    selectDrawType(newVal) {
      // 切换工具时重置比例尺绘制状态
      if (newVal !== 2) {
        this.resetScaleDrawing();
      }
    },
    externalScaleLine: {
        immediate: true,
        handler(newVal) {
            if (newVal && newVal.x1 && newVal.y1 && newVal.x2 && newVal.y2) {
                this.displayScaleLine(newVal);
            } else {
                this.resetScaleDrawing();
            }
        }
    }
  },
  mounted() {
    // 监听窗口大小变化，重新计算SVG容器偏移量
    window.addEventListener('resize', this.updateSvgBoxOffset);
    // 初始计算SVG容器偏移量
    this.$nextTick(() => {
      this.updateSvgBoxOffset();
    });
  },
  beforeDestroy() {
    this.cleanupImage();
    window.removeEventListener('resize', this.updateSvgBoxOffset);
  },
  methods: {
    updateSvgBoxOffset() {
      if (this.$refs.svgBox) {
        const rect = this.$refs.svgBox.getBoundingClientRect();
        this.svgBoxOffset = {
          left: rect.left + window.scrollX,
          top: rect.top + window.scrollY
        };
      }
    },
    
    calculationImage(url) {
      this.cleanupImage();
      
      this.imageRef = new Image();
      this.imageRef.src = url;
      this.imageLoading = true;

      this.imageRef.onload = () => {
        const imageWidth = this.imageRef.width;
        const imageHeight = this.imageRef.height;
        const boxWidth = this.$refs.svgBox?.offsetWidth || 800;
        const boxHeight = this.$refs.svgBox?.offsetHeight || 600;

        let width, height;

        if (imageWidth > boxWidth && imageHeight > boxHeight) {
          const a = boxWidth / imageWidth;
          const b = boxHeight / imageHeight;
          const c = Math.min(a, b);
          width = imageWidth * c;
          height = imageHeight * c;
        } else if (imageWidth > boxWidth) {
          width = boxWidth;
          height = imageHeight * (boxWidth / imageWidth);
        } else if (imageHeight > boxHeight) {
          width = imageWidth * (boxHeight / imageHeight);
          height = boxHeight;
        } else {
          width = imageWidth;
          height = imageHeight;
        }

        this.svgW = parseInt(width);
        this.svgH = parseInt(height);
        this.imageLoading = false;
        
        this.$emit('image-loaded', { width: this.svgW, height: this.svgH });
        
        // 图片加载完成后更新容器偏移量
        this.$nextTick(() => {
          this.updateSvgBoxOffset();
        });
      };

      this.imageRef.onerror = () => {
        this.imageLoading = false;
        this.$message.error('图片加载失败');
      };
    },

    cleanupImage() {
      if (this.imageRef) {
        this.imageRef.onload = null;
        this.imageRef.onerror = null;
        this.imageRef = null;
      }
    },

    handleUploadBg(file) {
      this.$emit('upload-bg', file);
    },

    handleCanvasMousedown(event) {
      if (this.selectDrawType === 1) {
        this.$emit('point-click', {
          x: event.offsetX,
          y: event.offsetY
        });
      } else if (this.selectDrawType === 6) {
        this.$emit('text-click', {
          x: event.offsetX,
          y: event.offsetY
        });
      } else if (this.selectDrawType === 2) {
        this.handleScaleDrawing(event);
      }
    },

    handleCanvasMousemove(event) {
      if (this.selectDrawType === 2 && this.isDrawingScale && this.scaleStartPoint) {
        this.tempScalePoint = {
          x: event.offsetX,
          y: event.offsetY
        };
        
        const dx = this.tempScalePoint.x - this.scaleStartPoint.x;
        const dy = this.tempScalePoint.y - this.scaleStartPoint.y;
        this.scaleLength = Math.sqrt(dx * dx + dy * dy);
      }
    },

    handleCanvasMouseup(event) {
      // 比例尺绘制完成处理
      if (this.selectDrawType === 2 && this.isDrawingScale && this.scaleStartPoint) {
        const endPoint = {
          x: event.offsetX,
          y: event.offsetY
        };
        this.finishScaleDrawing(endPoint);
      }
    },

    handleSvgMouseMove(data, evt) {
      this.pointToolShow = !!data.pointName;
      this.pointPlayer = data;
      
      // 使用SVG容器偏移量计算全局位置
      this.positonX = this.svgBoxOffset.left + evt.offsetX + 15;
      this.positonY = this.svgBoxOffset.top + evt.offsetY + 15;
    },

    handleSvgMouseLeave() {
      this.pointToolShow = false;
      this.pointPlayer = {};
      this.pointToolShowLine = false;
      this.lineTips = [];
    },

    handleDigitalizationMouseMove(data, evt){
      if(data.lineType == 1){
        this.pointToolShow = !!data.pointName;
        this.pointPlayer = data;
        
        // 使用SVG容器偏移量计算全局位置
        this.positonX = this.svgBoxOffset.left + evt.offsetX + 15;
        this.positonY = this.svgBoxOffset.top + evt.offsetY + 15;
      }else{
        this.pointToolShowLine = data.vl != '';
        if(data.vl != ''){
          this.lineTips = data.vl.split(',');
          if(this.lineTips.length > 2){
            const v = this.lineTips[2].split(' ');
            this.lineTips[2] = v[1];
          }
          
          // 使用SVG容器偏移量计算全局位置
          this.positonX = this.svgBoxOffset.left + evt.offsetX + 10;
          this.positonY = this.svgBoxOffset.top + evt.offsetY + 10;
        }
      }
    },

    // 比例尺相关方法
    handleScaleDrawing(event) {
      // 如果已有比例尺，点击则清除
      if (this.scaleLine) {
        this.resetScaleDrawing();
        return;
      }

      // 如果尚未开始绘制，设置起点
      if (!this.isDrawingScale) {
        this.scaleStartPoint = {
          x: event.offsetX,
          y: event.offsetY
        };
        this.isDrawingScale = true;
        this.tempScalePoint = { ...this.scaleStartPoint };
      } 
      // 如果已经开始绘制，设置终点
      else if (this.isDrawingScale && this.scaleStartPoint) {
        this.finishScaleDrawing({
          x: event.offsetX,
          y: event.offsetY
        });
      }
    },

    finishScaleDrawing(endPoint) {
      this.scaleLine = {
        x1: this.scaleStartPoint.x,
        y1: this.scaleStartPoint.y,
        x2: endPoint.x,
        y2: endPoint.y
      };

      const dx = this.scaleLine.x2 - this.scaleLine.x1;
      const dy = this.scaleLine.y2 - this.scaleLine.y1;
      this.scaleLength = Math.sqrt(dx * dx + dy * dy);

      this.isDrawingScale = false;
      this.scaleStartPoint = null;
      this.tempScalePoint = null;

      this.$emit('scale-drawn', {
        x1: this.scaleLine.x1,
        y1: this.scaleLine.y1,
        x2: this.scaleLine.x2,
        y2: this.scaleLine.y2
      });
    },

    resetScaleDrawing() {
      this.isDrawingScale = false;
      this.scaleStartPoint = null;
      this.tempScalePoint = null;
      this.scaleLine = null;
      this.scaleLength = 0;
    },

    getTempScaleMarks(startPoint, endPoint) {
      const marks = [];
      const dx = endPoint.x - startPoint.x;
      const dy = endPoint.y - startPoint.y;
      const length = Math.sqrt(dx * dx + dy * dy);
      
      if (length === 0) return marks;
      
      // 计算垂直方向向量
      const perpx = -dy / length;
      const perpy = dx / length;
      
      const markSpacing = 10; // 刻度间隔
      const numMarks = Math.floor(length / markSpacing);
      
      for (let i = 0; i <= numMarks; i++) {
        const t = i * markSpacing / length;
        const markX = startPoint.x + dx * t;
        const markY = startPoint.y + dy * t;
        const isLong = i % 5 === 0; // 每5个刻度一个长刻度
        const markLength = isLong ? 12 : 6;
        
        // 计算刻度线的终点
        const markEndX = markX + perpx * markLength;
        const markEndY = markY + perpy * markLength;
        
        marks.push({
          x1: markX,
          y1: markY,
          x2: markEndX,
          y2: markEndY
        });
      }
      
      return marks;
    },

    getScaleMarks(line) {
      const startPoint = { x: line.x1, y: line.y1 };
      const endPoint = { x: line.x2, y: line.y2 };
      return this.getTempScaleMarks(startPoint, endPoint);
    },
    
    displayScaleLine(scaleData) {
        this.scaleLine = {
            x1: scaleData.x1,
            y1: scaleData.y1,
            x2: scaleData.x2,
            y2: scaleData.y2
        };
        
        const dx = this.scaleLine.x2 - this.scaleLine.x1;
        const dy = this.scaleLine.y2 - this.scaleLine.y1;
        this.scaleLength = Math.sqrt(dx * dx + dy * dy);
        
        this.isDrawingScale = false;
        this.scaleStartPoint = null;
        this.tempScalePoint = null;
    },
  }
};
</script>

<style scoped lang="scss">
.imageViewer {
  margin: 0 10px;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: relative;
  background: #f8f9fa;
  border-radius: 8px;
  padding: 15px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);

  .uploadFile {
    width: 360px;
    height: 180px;
    border: 2px dashed #d1d8e0;
    border-radius: 8px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s ease;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;

    &:hover {
      border-color: #409eff;
      box-shadow: 0 4px 12px rgba(32, 160, 255, 0.15);
      transform: translateY(-2px);
    }

    .upload-content {
      i {
        font-size: 48px;
        color: #c0c4cc;
        margin-bottom: 12px;
        display: block;
      }

      .upload-text {
        color: #606266;
        font-size: 16px;
        font-weight: 500;
        margin: 0 0 8px 0;
      }

      .upload-subtext {
        color: #909399;
        font-size: 12px;
        margin: 0;
      }
    }
  }

  #svgBox {
    position: relative;
    border-radius: 6px;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    background: #fff;
  }

  .measure-point {
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
    transition: r 0.2s ease;
    
    &:hover {
      r: 7;
      stroke-width: 3;
    }
  }

  .scale-text {
    filter: drop-shadow(0 1px 1px rgba(255, 255, 255, 0.8));
  }

  .pointTool {
    position: fixed; /* 使用fixed定位确保弹窗位于视图最上层 */
    z-index: 9999; /* 提高z-index确保在最顶层 */
    background: #fff;
    border-radius: 8px;
    box-sizing: border-box;
    padding: 0;
    color: #606266;
    font-size: 13px;
    pointer-events: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    border: 1px solid #e6e8eb;
    min-width: 180px;
    overflow: hidden;

    .point-tool-header {
      background: #f5f7fa;
      padding: 10px 15px;
      border-bottom: 1px solid #e6e8eb;
      font-weight: 600;
      display: flex;
      align-items: center;
      
      i {
        margin-right: 5px;
        color: #409eff;
      }
    }

    .point-tool-content {
      padding: 12px 15px;
      
      p {
        margin: 8px 0;
        line-height: 1.4;
        display: flex;
        justify-content: space-between;
        
        .label {
          color: #909399;
          font-weight: 500;
        }
        
        .color-badge {
          display: inline-block;
          width: 12px;
          height: 12px;
          border-radius: 2px;
          vertical-align: middle;
          box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
        }
      }
    }
  }
}

.tips {
  position: absolute;
  top: 6px;
  width: 90%;
  left: 5%;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>